/*
 * TraceVariable.c
 *
 *  Created on: 2012/07/10
 *      Author: guanxiaoying
 */

#include <float.h>
#include "../tracedef.h"
#include "trace_cmd.h"
VOID Tr_VariGetScope( AST astTrVari, TRVALUESCP *pstVarScope ){
	assert( pstVarScope != NULL );
	if( astTrVari == 0 ){
		Tr_ScpSetInvalid(pstVarScope);
	}else{
		stTrVariableAccess.getValueScope( astTrVari, pstVarScope );
	}
}
VOID Tr_VariSetScope( AST astTrVari, TRVALUESCP *pstVarScope ){
	assert( pstVarScope != NULL );
	if( astTrVari != 0 ){
		stTrVariableAccess.setValueScope( astTrVari, pstVarScope );
	}
}
VOID Tr_VariGetNegationScope( AST astTrVari, TRVALUESCP *pstVarScope ){
	assert( pstVarScope != NULL );
	if( astTrVari == 0 ){
		pstVarScope->usScopeKind = SCOPEKIND_VOID;
	}else{
		stTrVariableAccess.getNegValueScope( astTrVari, pstVarScope );
	}
}
VOID Tr_VariSetNegationScope( AST astTrVari, TRVALUESCP *pstVarScope ){
	assert( pstVarScope != NULL );
	if( astTrVari != 0 ){
		stTrVariableAccess.setNegValueScope( astTrVari, pstVarScope );
	}
}
VOID Tr_VariClearAllFlag( AST astTrVari ){
	if( astTrVari != 0 ){
		stTrVariableAccess.flag.set( astTrVari, 0 );
	}
}
VOID Tr_VariAddFlag( AST astTrVari, U4 addFlag ){
	if( astTrVari != 0 ){
		U4 flag = stTrVariableAccess.flag.get( astTrVari );
		stTrVariableAccess.flag.set( astTrVari, flag | addFlag );
	}
}
VOID Tr_VariDeleteFlag( AST astTrVari, U4 delFlag ){
	if( astTrVari != 0 ){
		U4 flag = stTrVariableAccess.flag.get( astTrVari );
		stTrVariableAccess.flag.set( astTrVari, flag & ~delFlag );
	}
}
VOID Tr_VariClearAllAttribute( AST astTrVari ){
	if( astTrVari != 0 ){
		stTrVariableAccess.attribute.set( astTrVari, 0 );
	}
}
VOID Tr_VariAddAttribute( AST astTrVari, U4 addAttr ){
	if( astTrVari != 0 ){
		U4 attr = stTrVariableAccess.flag.get( astTrVari );
		stTrVariableAccess.attribute.set( astTrVari, attr | addAttr );
	}
}
VOID Tr_VariDeleteAttribute( AST astTrVari, U4 delAttr ){
	if( astTrVari != 0 ){
		U4 attr = stTrVariableAccess.flag.get( astTrVari );
		stTrVariableAccess.flag.set( astTrVari, attr & ~delAttr );
	}
}
VOID Tr_VariResetScope( AST astTrVari ){
	TRVALUESCP stValueScp;
	AST astType;
	if ( astTrVari > 0 ){
		if( Tr_VariNeedCalcuteScp( astTrVari ) ){
			astType = LinkVariable.getType( stTrVariableAccess.variable.get( astTrVari ) );
			Tr_ScpGetScpByType( astType, &stValueScp );
			Tr_VariSetScope( astTrVari, &stValueScp );
			Tr_VariSetNegationScope( astTrVari, &stValueScp );
		}
	}
}
AST Tr_VariNew( AST astVari ){
	AST astTrVari=0;
	AST astType;
	TRVALUESCP stValueScp;
	if( astVari > 0 ){
		stTrVariableAccess.alloc(1);
		astTrVari = stTrVariableAccess.getMax();
		stTrVariableAccess.variable.set( astTrVari, astVari );
		astType = LinkVariable.getType( astVari );
		if( LinkTypeInfo.isInteger( astType ) || LinkTypeInfo.isFloating( astType )
			|| LinkTypeInfo.isBitfield( astType ) || LinkTypeInfo.isEnum( astType )){
			stTrVariableAccess.flag.set( astTrVari, TRVARI_CALCUTE );
			Tr_ScpGetScpByType( astType, &stValueScp );
			Tr_VariSetScope( astTrVari, &stValueScp );
			Tr_VariSetNegationScope( astTrVari, &stValueScp );
		}
	}
	return astTrVari;
}
VOID Tr_VariClearScope( AST astVari ){
	TRVALUESCP stValueScp;
	if( astVari > 0 ){
		Tr_ScpGetScpByType( LinkVariable.getType( astVari ), &stValueScp );
		Tr_ScpSetInvalid(&stValueScp);
		stTrVariableAccess.setValueScope( astVari, &stValueScp );
	}
}
VOID Tr_VariOrMergeValue( AST astTrVarOrg, AST astTrVarDst ){
	TRVALUESCP stLeft, stRight, stResult;

	stTrVariableAccess.getValueScope( astTrVarDst, &stLeft );
	stTrVariableAccess.getValueScope( astTrVarOrg, &stRight );
	Tr_ScpMergeOrOr( &stLeft, &stRight, &stResult );
	stTrVariableAccess.setValueScope( astTrVarDst, &stResult );

	stTrVariableAccess.getNegValueScope( astTrVarDst, &stLeft );
	stTrVariableAccess.getNegValueScope( astTrVarOrg, &stRight );
	Tr_ScpMergeAndAnd( &stLeft, &stRight, &stResult );
	stTrVariableAccess.setNegValueScope( astTrVarDst, &stResult );
}
VOID Tr_VariAndMergeValue( AST astTrVarOrg, AST astTrVarDst ){
	TRVALUESCP stLeft, stRight, stResult;

	stTrVariableAccess.getValueScope( astTrVarDst, &stLeft );
	stTrVariableAccess.getValueScope( astTrVarOrg, &stRight );
	Tr_ScpMergeAndAnd( &stLeft, &stRight, &stResult );
	stTrVariableAccess.setValueScope( astTrVarDst, &stResult );

	stTrVariableAccess.getNegValueScope( astTrVarDst, &stLeft );
	stTrVariableAccess.getNegValueScope( astTrVarOrg, &stRight );
	Tr_ScpMergeOrOr( &stLeft, &stRight, &stResult );
	stTrVariableAccess.setNegValueScope( astTrVarDst, &stResult );
}
VOID Tr_VariReplaceValue( AST astTrVarOrg, AST astTrVarDst ){
	TRVALUESCP stLeft;

	stTrVariableAccess.getValueScope( astTrVarOrg, &stLeft );
	stTrVariableAccess.setValueScope( astTrVarDst, &stLeft );
	stTrVariableAccess.getNegValueScope( astTrVarOrg, &stLeft );
	stTrVariableAccess.setNegValueScope( astTrVarDst, &stLeft );
}
BOOL Tr_VariHasValue( AST astVari ){
	TRVALUESCP stValueScp;
	if( astVari == 0 ){
		return FALSE;
	}else{
		stTrVariableAccess.getValueScope( astVari, &stValueScp );
		if( Tr_ScpHasValue( &stValueScp ) ){
			return TRUE;
		}
		return FALSE;
	}
}
AST Tr_VariGetVari( AST astTrVari ){
	return stTrVariableAccess.variable.get( astTrVari );
}
BOOL Tr_VariNeedCalcuteScp( AST astTrVari ){
	return stTrVariableAccess.flag.get( astTrVari ) & TRVARI_CALCUTE;
}
BOOL Tr_VariIsLoopCnter( AST astTrVari ) {
	return stTrVariableAccess.flag.get( astTrVari ) & TRVARI_LOOPCNTER;
}
VOID Tr_VariReverseScope( AST var ){
	TRVALUESCP stValueScp;
	TRVALUESCP stValueNegScp;
	stTrVariableAccess.getValueScope( var, &stValueScp );
	stTrVariableAccess.getNegValueScope( var, &stValueNegScp );

	stTrVariableAccess.setValueScope( var, &stValueNegScp );
	stTrVariableAccess.setNegValueScope( var, &stValueScp );
}
VOID Tr_VariCopyNegationScp( AST astTrVari ){
	TRVALUESCP stValueScp;
	stTrVariableAccess.getValueScope( astTrVari, &stValueScp );
	stTrVariableAccess.setNegValueScope( astTrVari, &stValueScp );
}
